﻿namespace NTLib.Pipe
{
    using NTLib.Core.Args;
    using NTLib.Pipe.Descriptors;
    using NTLib.Pipe.Targets;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Pipe's source interface use to exchange data through everything.
    /// </summary>
    public interface IPipe : IDisposable
    {
        #region Properties

        /// <summary>
        /// Gets the unique ID.
        /// </summary>
        Guid Id { get; }

        /// <summary>
        /// Gets the type of the pipe.
        /// </summary>
        PipeType PipeType { get; }

        /// <summary>
        /// Gets the status.
        /// </summary>
        PipeStatus Status { get; }

        #endregion

        #region Event

        /// <summary>
        /// Occurs when the status changed.
        /// </summary>
        event EventHandler<ValueChangedEventArgs<PipeStatus>> StatusChanged;

        #endregion
    }

    /// <summary>
    /// Pipe interface use to exchange data through everything.
    /// </summary>
    /// <typeparam name="T">Type item that will navigate through.</typeparam>
    public interface IPipe<T> : IPipe
    {

        #region Methods

        /// <summary>
        /// Pop an item from the item's queue if the pipe permits it.
        /// </summary>
        /// <param name="token">Token used to cancel the task of waiting item.</param>
        /// <returns>Asynchronious task that wait there is an item in the pipe.</returns>
        Task<T> PopAsync(CancellationToken token = default(CancellationToken));

        ///// <summary>
        ///// Push an item to the item's queue if the pipe permits it and wait that the item is process by the other side.
        ///// </summary>
        ///// <typeparam name="U">Type of the response you are waiting by this specific push.</typeparam>
        ///// <param name="item">The item.</param>
        ///// <param name="token">Tpken used to cancel the task that wait to items arrived on the other side.</param>
        ///// <returns>
        ///// Asynchronious task that permit to wait that the item have been pop by the other side.
        ///// </returns>
        //Task<U> PushAsync<U>(T item, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Send an item to the item's queue if the pipe permits it.
        /// Attention this method doesn't wait that the item achieved the other side.
        /// </summary>
        /// <param name="item">Item to send</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        Task SendAsync(T item, CancellationToken token = default(CancellationToken));

        #endregion
    }
}
